package cn.starremote.component.utils;

import com.sun.jdi.Bootstrap;
import com.sun.jdi.VMDisconnectedException;
import com.sun.jdi.VirtualMachine;
import com.sun.jdi.VirtualMachineManager;
import com.sun.jdi.connect.AttachingConnector;
import com.sun.jdi.connect.Connector;
import com.sun.jdi.event.*;
import com.sun.jdi.request.BreakpointRequest;
import com.sun.jdi.request.EventRequestManager;
import com.sun.jdi.request.MethodEntryRequest;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;

@Slf4j
public class CustomRemoteDebugger {

    public static void main(String[] args) {
        // 远程调试连接信息
        String host = "localhost";
        int port = 8000;

        // 连接到远程 JVM
        VirtualMachine vm = connectToRemoteVM(host, port);

        // 添加事件请求
        addEventRequests(vm.eventRequestManager());

        // 处理调试事件
        processDebugEvents(vm.eventQueue());

        // 断开连接
        disconnectFromRemoteVM(vm);
    }

    private static VirtualMachine connectToRemoteVM(String host, int port) {
        VirtualMachineManager vmManager = Bootstrap.virtualMachineManager();

        try {
            AttachingConnector connector = findConnector(vmManager);

            Map<String, Connector.Argument> connectorArgs = connector.defaultArguments();
            connectorArgs.get("hostname").setValue(host);
            connectorArgs.get("port").setValue(String.valueOf(port));

            VirtualMachine vm = connector.attach(connectorArgs);

            log.info("Connected to remote VM: " + vm.name());
            return vm;
        } catch (Exception e) {
            log.error("Failed to connect to remot:{}",e);
            throw new RuntimeException("Failed to connect to remote VM");
        }
    }

    private static AttachingConnector findConnector(VirtualMachineManager vmManager) {
        for (AttachingConnector connector : vmManager.attachingConnectors()) {
            if ("dt_socket".equals(connector.transport())) {
                return connector;
            }
        }
        throw new RuntimeException("No suitable connector found");
    }

    private static void addEventRequests(EventRequestManager requestManager) {
        // 添加你需要的事件请求
        MethodEntryRequest methodEntryRequest = requestManager.createMethodEntryRequest();
        methodEntryRequest.enable();

    }

    private static void processDebugEvents(EventQueue eventQueue) {
        while (true) {
            try {
                EventSet eventSet = eventQueue.remove();
                for (Event event : eventSet) {
                    // 处理不同类型的事件
                    if (event instanceof MethodEntryEvent) {
                        MethodEntryEvent methodEntryEvent = (MethodEntryEvent) event;
                        System.out.println("Method Entry: " + methodEntryEvent.location());
                    } else if (event instanceof BreakpointEvent) {
                        BreakpointEvent breakpointEvent = (BreakpointEvent) event;
                        System.out.println("Breakpoint Hit: " + breakpointEvent.location());
                    }
                }
                eventSet.resume();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private static void disconnectFromRemoteVM(VirtualMachine vm) {
        try {
            vm.dispose();
            System.out.println("Disconnected from remote VM");
        } catch (VMDisconnectedException e) {
            // VMDisconnectedException is expected upon disconnect
        }
    }
}
